package com.ai.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.ai.entity.SysDeptEntity;
import com.ai.entity.SysRoleEntity;
import com.ai.entity.SysUserEntity;
import com.ai.exception.BusinessException;
import com.ai.exception.code.BaseResponseCode;
import com.ai.mapper.SysDeptMapper;
import com.ai.mapper.SysRoleMapper;
import com.ai.mapper.SysUserMapper;
import com.ai.service.RoleService;
import com.ai.service.UserRoleService;
import com.ai.service.UserService;
import com.ai.utils.ConvertUtils;
import com.ai.utils.PasswordUtils;
import com.ai.web.PageResp;
import com.ai.web.request.*;
import com.ai.web.response.LoginResp;
import com.ai.web.response.UserDetailResp;
import com.ai.web.response.UserOwnRoleResp;
import com.ai.web.response.UserPageResp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户管理service
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    RoleService roleService;
    @Resource
    UserRoleService userRoleService;
    @Resource
    SysDeptMapper sysDeptMapper;
    @Resource
    SysRoleMapper sysRoleMapper;

    @Value("${spring.profiles.active}")
    private String env;

    @Override
    public void deleteUser(List<String> userIds) {
        sysUserMapper.delete(Wrappers.<SysUserEntity>lambdaQuery().in(SysUserEntity::getId, userIds));
    }

    @Override
    public void register(UserAddReq userAddReq) {
        addUser(userAddReq);
    }


    @Override
    public LoginResp login(LoginReq vo) {
        SysUserEntity sysUser = sysUserMapper.selectOne(Wrappers.<SysUserEntity>lambdaQuery().eq(SysUserEntity::getUsername, vo.getUsername()));
        if (null == sysUser) {
            throw new BusinessException(BaseResponseCode.NOT_ACCOUNT);
        }
        if (sysUser.getStatus() == 2) {
            throw new BusinessException(BaseResponseCode.USER_LOCK);
        }
        if (!PasswordUtils.matches(sysUser.getSalt(), vo.getPassword(), sysUser.getPassword())) {
            throw new BusinessException(BaseResponseCode.PASSWORD_ERROR);
        }
        LoginResp respVO = new LoginResp();
        respVO.setId(sysUser.getId());
        respVO.setUsername(sysUser.getUsername());
        respVO.setPhone(sysUser.getPhone());
        //saToken
        StpUtil.login(sysUser.getId());
        return respVO;
    }

    @Override
    public void updateUserInfo(UserUpdateReq userUpdateReq) {
        SysUserEntity sysUser = sysUserMapper.selectById(userUpdateReq.getId());
        if (null == sysUser) {
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }

        //如果用户名变更
        if (!sysUser.getUsername().equals(userUpdateReq.getUsername())) {
            SysUserEntity sysUserOne = sysUserMapper.selectOne(Wrappers.<SysUserEntity>lambdaQuery().eq(SysUserEntity::getUsername, userUpdateReq.getUsername()));
            if (sysUserOne != null) {
                throw new BusinessException("用户名已存在！");
            }
        }

        SysUserEntity convert = ConvertUtils.convert(userUpdateReq, SysUserEntity.class);

        if (!StringUtils.isEmpty(userUpdateReq.getPassword())) {
            String newPassword = PasswordUtils.encode(userUpdateReq.getPassword(), sysUser.getSalt());
            convert.setPassword(newPassword);
        } else {
            convert.setPassword(null);
        }
        sysUserMapper.updateById(convert);

    }

    @Override
    public UserDetailResp findById(String id) {
        SysUserEntity sysUser = sysUserMapper.selectById(id);
        return ConvertUtils.convert(sysUser,UserDetailResp.class);
    }

    @Override
    public void updateUserInfoMy(UserUpdateReq userUpdateReq) {
        userUpdateReq.setId(StpUtil.getLoginIdAsString());
        updateUserInfo(userUpdateReq);
    }

    @Override
    public PageResp<UserPageResp> pageInfo(UserPageReq userPageReq) {
        LambdaQueryWrapper<SysUserEntity> queryWrapper = Wrappers.lambdaQuery();
        if (!StringUtils.isEmpty(userPageReq.getUsername())) {
            queryWrapper.like(SysUserEntity::getUsername, userPageReq.getUsername());
        }
        if (!StringUtils.isEmpty(userPageReq.getStartTime())) {
            queryWrapper.gt(SysUserEntity::getCreateTime, userPageReq.getStartTime());
        }
        if (!StringUtils.isEmpty(userPageReq.getEndTime())) {
            queryWrapper.lt(SysUserEntity::getCreateTime, userPageReq.getEndTime());
        }
        if (!StringUtils.isEmpty(userPageReq.getNickName())) {
            queryWrapper.like(SysUserEntity::getNickName, userPageReq.getNickName());
        }
        if (null != userPageReq.getStatus()) {
            queryWrapper.eq(SysUserEntity::getStatus, userPageReq.getStatus());
        }
        if (!StringUtils.isEmpty(userPageReq.getDeptNo())) {
            LambdaQueryWrapper<SysDeptEntity> queryWrapperDept = Wrappers.lambdaQuery();
            queryWrapperDept.select(SysDeptEntity::getId).like(SysDeptEntity::getRelationCode, userPageReq.getDeptNo());
            List<Object> list = sysDeptMapper.selectObjs(queryWrapperDept);
            queryWrapper.in(SysUserEntity::getDeptId, list);
        }
        queryWrapper.orderByDesc(SysUserEntity::getCreateTime);
        IPage<SysUserEntity> iPage = sysUserMapper.selectPage(new Page<>(userPageReq.getPage(), userPageReq.getLimit()), queryWrapper);
        return ConvertUtils.convertPageResp(iPage, e->{
            UserPageResp userPageResp = ConvertUtils.convert(e, UserPageResp.class);
            SysDeptEntity sysDept = sysDeptMapper.selectById(e.getDeptId());
            if (sysDept != null) {
                userPageResp.setDeptName(sysDept.getName());
            }
            return userPageResp;
        });
    }

    @Override
    public void addUser(UserAddReq userAddReq) {
        SysUserEntity sysUserOne = sysUserMapper.selectOne(Wrappers.<SysUserEntity>lambdaQuery().eq(SysUserEntity::getUsername, userAddReq.getUsername()));
        if (sysUserOne != null) {
            throw new BusinessException("用户已存在，请勿重复添加！");
        }
        SysUserEntity sysUserNew = new SysUserEntity();
        sysUserNew.setSalt(PasswordUtils.getSalt());
        sysUserNew.setUsername(userAddReq.getUsername());
        String encode = PasswordUtils.encode(userAddReq.getPassword(), sysUserNew.getSalt());
        sysUserNew.setUsername(userAddReq.getUsername());
        sysUserNew.setPassword(encode);
        sysUserNew.setStatus(1);
        sysUserNew.setCreateWhere(1);
        sysUserNew.setPhone(userAddReq.getPhone());
        sysUserNew.setEmail(userAddReq.getEmail());
        sysUserNew.setRealName(userAddReq.getRealName());
        sysUserNew.setSex(userAddReq.getSex());
        sysUserNew.setNickName(userAddReq.getRealName());
        int insert = sysUserMapper.insert(sysUserNew);
        log.info("添加用户信息:{},{}insert", userAddReq, insert);

    }

    @Override
    public void updatePwd(UserUpdatePwdReq userUpdatePwdReq) {

        if (org.springframework.util.StringUtils.isEmpty(userUpdatePwdReq.getOldPwd()) || org.springframework.util.StringUtils.isEmpty(userUpdatePwdReq.getNewPwd())) {
            throw new BusinessException("旧密码与新密码不能为空");
        }

        SysUserEntity sysUser = sysUserMapper.selectById(userUpdatePwdReq.getId());
        if (sysUser == null) {
            throw new BusinessException(BaseResponseCode.DATA_ERROR);
        }
        if ("test".equals(env) && "guest".equals(sysUser.getUsername())) {
            throw new BusinessException("演示环境禁止修改演示账号密码");
        }

        if (!PasswordUtils.matches(sysUser.getSalt(), userUpdatePwdReq.getOldPwd(), sysUser.getPassword())) {
            throw new BusinessException(BaseResponseCode.OLD_PASSWORD_ERROR);
        }
        if (sysUser.getPassword().equals(PasswordUtils.encode(userUpdatePwdReq.getNewPwd(), sysUser.getSalt()))) {
            throw new BusinessException("新密码不能与旧密码相同");
        }
        sysUser.setPassword(PasswordUtils.encode(userUpdatePwdReq.getNewPwd(), sysUser.getSalt()));
        sysUserMapper.updateById(sysUser);
    }

    @Override
    public UserOwnRoleResp getUserOwnRole(String userId) {
        List<String> roleIdsByUserId = userRoleService.getRoleIdsByUserId(userId);
        List<SysRoleEntity> list = sysRoleMapper.selectList(null);

        UserOwnRoleResp vo = new UserOwnRoleResp();
        vo.setAllRole(list);
        vo.setOwnRoles(roleIdsByUserId);
        return vo;
    }
}
